#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <cstdio>

typedef void *(*fun_t)(void *);

class ThreadData
{
public:
    void *args_;
    std::string name_;
};

class Thread
{
private:
    fun_t func_;
    ThreadData data_;
    pthread_t tid_;
    std::string name_;

public:
    Thread(int num, fun_t callback, void *args)
        : func_(callback)
    {
        char nameBuffer[64] = {0};
        snprintf(nameBuffer, sizeof nameBuffer, "Thread %d", num);
        name_ = nameBuffer;
        data_.args_ = args;
        data_.name_ = name_;
    }

    void start()
    {
        pthread_create(&tid_, NULL, func_, (void *)&data_);
    }

    void join()
    {
        pthread_join(tid_, NULL);
    }

    std::string name()
    {
        return data_.name_;
    }
};